/**
 * <b>项目名称：</b>网络应用框架<br/>
 * <b>包    名：</b>com.hhwy.framework.persistent.query.impl<br/>
 * <b>文 件 名：</b>WhereClauseImpl.java<br/>
 * <b>版本信息：</b><br/>
 * <b>日    期：</b>2014年8月2日-上午9:08:34<br/>
 * <b>Copyright (c)</b> 2014恒华伟业科技股份有限公司-版权所有<br/>
 * 
 */
package com.hhwy.framework.persistent.query.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.hhwy.framework.persistent.query.IWhereClause;
import com.hhwy.framework.util.StringUtils;

/**
 * <b>类 名 称：</b>WhereClauseImpl 组织where子句、排序条件<br/>
 * <b>类 描 述：</b><br/>
 * <b>创 建 人：</b>lihuiming<br/>
 * <b>修 改 人：</b>lihuiming<br/>
 * <b>修改时间：</b>2014年8月2日 上午9:08:34<br/>
 * <b>修改备注：</b><br/>
 * 
 * @version 1.0.0<br/>
 */
@Component
@Scope("prototype")
public class WhereClauseImpl implements IWhereClause {

	private StringBuffer whereClause = new StringBuffer();
	private List<Map<String, Object>> queryParamsList = new ArrayList<>();
	private List<Map<String, String>> orderParamsList = new ArrayList<>();

	@Override
	public String whereJpql() {
		return whereClause.toString();
	}

	@Override
	public List<Map<String, Object>> queryParams() {
		return queryParamsList;
	}

	@Override
	public List<Map<String, String>> orderParams() {
		return orderParamsList;
	}

	public IWhereClause andSubClause(String subClause) {
		if (subClause == null || subClause.length() == 0)
			return this;

		if (whereClause.length() > 0)
			whereClause.append(" and ");

		whereClause.append(subClause);
		return this;
	}

	public IWhereClause orSubClause(String subClause) {
		if (subClause == null || subClause.length() == 0)
			return this;

		if (whereClause.length() > 0)
			whereClause.append(" or ");

		whereClause.append(subClause);

		return this;
	}

	public IWhereClause orBrackets(IWhereClause where) {
		if (where.whereJpql().length() == 0)
			return this;

		if (whereClause.length() > 0)
			whereClause.append(" or ");
		whereClause.append("(").append(where.whereJpql()).append(") ");

		queryParamsList.addAll(where.queryParams());
		return this;
	}

	public IWhereClause andBrackets(IWhereClause where) {
		if (where.whereJpql().length() == 0)
			return this;

		if (whereClause.length() > 0)
			whereClause.append(" and ");
		whereClause.append("(").append(where.whereJpql()).append(") ");
		queryParamsList.addAll(where.queryParams());
		return this;
	}

	public IWhereClause andLT(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLT(property, value);
		return this;
	}

	@Override
	public IWhereClause andLT(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLT(property, alias, value);
		return this;
	}

	public IWhereClause orLT(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLT(property, value);
		return this;
	}

	@Override
	public IWhereClause orLT(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLT(property, alias, value);
		return this;

	}

	private void setLT(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append("<").append(":")
				.append(alias).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);
		queryParamsList.add(map);

	}

	@Override
	public IWhereClause andLTE(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLTE(property, value);
		return this;
	}

	/**
	 * setLTE(描述这个方法的作用)<br/>
	 * 
	 * @param property
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setLTE(String property, Object value) {
		whereClause.append(" o.").append(property).append("<=").append(":")
				.append(property).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(property, value);
		queryParamsList.add(map);

	}

	@Override
	public IWhereClause andLTE(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLTE(property, value);
		return this;
	}

	@Override
	public IWhereClause orLTE(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLTE(property, value);
		return this;
	}

	@Override
	public IWhereClause orLTE(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLTE(property, alias, value);
		return this;
	}

	/**
	 * setLTE(描述这个方法的作用)<br/>
	 * 
	 * @param property
	 * @param alias
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setLTE(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append("<=").append(":")
				.append(alias).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);
		queryParamsList.add(map);

	}

	/**
	 * setLT(添加小于条件)<br/>
	 * 
	 * @param property
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setLT(String property, Object value) {
		whereClause.append(" o.").append(property).append("<").append(":")
				.append(property).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(property, value);
		queryParamsList.add(map);
	}

	public IWhereClause andGT(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setGT(property, value);
		return this;
	}

	@Override
	public IWhereClause andGT(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setGT(property, alias, value);
		return this;
	}

	public IWhereClause orGT(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setGT(property, value);
		return this;
	}

	@Override
	public IWhereClause orGT(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setGT(property, alias, value);
		return this;
	}

	private void setGT(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append(">").append(":")
				.append(alias).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);
		queryParamsList.add(map);
	}

	/**
	 * setGT(添加大于条件)<br/>
	 * 
	 * @param property
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setGT(String property, Object value) {
		if (StringUtils.isNull(value))
			return;
		whereClause.append(" o.").append(property).append(">").append(":")
				.append(property).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(property, value);
		queryParamsList.add(map);
	}

	@Override
	public IWhereClause andGTE(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setGTE(property, value);
		return this;
	}

	/**
	 * setGTE(描述这个方法的作用)<br/>
	 * 
	 * @param property
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setGTE(String property, Object value) {
		if (StringUtils.isNull(value))
			return;
		whereClause.append(" o.").append(property).append(">=").append(":")
				.append(property).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(property, value);
		queryParamsList.add(map);

	}

	@Override
	public IWhereClause andGTE(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setGTE(property, alias, value);
		return this;
	}

	/**
	 * setGTE(描述这个方法的作用)<br/>
	 * 
	 * @param property
	 * @param alias
	 * @param value
	 *            void
	 * @exception
	 * @since 1.0.0
	 */
	private void setGTE(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append(">=").append(":")
				.append(alias).append(" ");
		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);
		queryParamsList.add(map);

	}

	@Override
	public IWhereClause orGTE(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setGTE(property, value);
		return this;
	}

	@Override
	public IWhereClause orGTE(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setGTE(property, alias, value);
		return this;
	}

	@Override
	public IWhereClause andNot(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");

		notEquals(property, value);
		return this;
	}

	@Override
	public IWhereClause andNot(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");

		notEquals(property, alias, value);
		return this;
	}

	@Override
	public IWhereClause orNot(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		notEquals(property, value);
		return this;
	}

	@Override
	public IWhereClause orNot(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		notEquals(property, alias, value);
		return this;
	}

	private void notEquals(String property, String alias, Object value) {

		whereClause.append(" o.").append(property).append("<>").append(":")
				.append(alias).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);

		queryParamsList.add(map);
	}

	private void notEquals(String property, Object value) {

		whereClause.append(" o.").append(property).append("<>").append(":")
				.append(property).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(property, value);

		queryParamsList.add(map);
	}

	@Override
	public IWhereClause and(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setEquals(property, value);
		return this;
	}

	@Override
	public IWhereClause and(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setEquals(property, alias, value);
		return this;
	}

	@Override
	public IWhereClause or(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");

		setEquals(property, value);
		return this;
	}

	@Override
	public IWhereClause or(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");

		setEquals(property, alias, value);
		return this;
	}

	private void setEquals(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append("=").append(":")
				.append(alias).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);

		queryParamsList.add(map);
	}

	private void setEquals(String property, Object value) {
		whereClause.append(" o.").append(property).append("=").append(":")
				.append(property).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(property, value);

		queryParamsList.add(map);
	}

	@Override
	public IWhereClause andLike(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLike(property, value);
		return this;
	}

	@Override
	public IWhereClause andLike(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" and ");
		setLike(property, alias, value);
		return this;
	}

	@Override
	public IWhereClause orLike(String property, Object value) {
		if (StringUtils.isNull(value))
			return this;
		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLike(property, value);
		return this;
	}

	@Override
	public IWhereClause orLike(String property, String alias, Object value) {
		if (StringUtils.isNull(value))
			return this;

		if (whereClause.length() > 0)
			whereClause.append(" or ");
		setLike(property, alias, value);
		return this;
	}

	private void setLike(String property, String alias, Object value) {
		whereClause.append(" o.").append(property).append(" like ").append(":")
				.append(alias).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(alias, value);

		queryParamsList.add(map);
	}

	private void setLike(String property, Object value) {
		whereClause.append(" o.").append(property).append(" like ").append(":")
				.append(property).append(" ");

		Map<String, Object> map = new HashMap<>();
		map.put(property, value);

		queryParamsList.add(map);
	}

	@Override
	public IWhereClause addOrder(String property, String orderType) {
		Map<String, String> map = new HashMap<>();
		map.put(property, orderType);
		orderParamsList.add(map);
		return this;
	}

	@Override
	public IWhereClause addDescOrder(String property) {
		Map<String, String> map = new HashMap<>();
		map.put(property, "DESC");
		orderParamsList.add(map);
		return this;
	}

	@Override
	public IWhereClause addAscOrder(String property) {
		Map<String, String> map = new HashMap<>();
		map.put(property, "ASC");
		orderParamsList.add(map);
		return this;
	}

	public IWhereClause addOrder(Map<String, String> orderParams) {
		orderParamsList.add(orderParams);
		return this;
	}

}
